/**
 * 
 */
package br.com.sistransporte.transite.onibus.dao;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import org.hibernate.Query;
import org.hibernate.Session;

import br.com.sistransporte.transitevo.linha.model.LinhaVO;
import br.com.sistransporte.transitevo.onibus.model.OnibusVO;
import br.com.src.masterpersistence.dao.GenericDAO;
import br.com.src.masterpersistence.exceptions.AlterarException;
import br.com.src.masterpersistence.exceptions.ExcluirException;
import br.com.src.masterpersistence.exceptions.FiltrarException;
import br.com.src.masterpersistence.exceptions.HibernatePersistenceException;
import br.com.src.masterpersistence.exceptions.InserirException;
import br.com.src.masterpersistence.utilidades.FabricaMensagensLog;
import br.com.src.masterpersistence.utilidades.Paginacao;
import br.com.src.utilidades.exceptions.DesconhecidoException;

/**
 * Classe que representa
 *
 *
 * @author Nelson Luis da Silva Junior <nelson.jr13@hotmail.com@>
 * @since 3 de Jul de 2013 16:33:06
 * @version 1.0
 */
public class OnibusDAOImpl extends GenericDAO< OnibusVO > implements OnibusDAOService{

	public OnibusDAOImpl(String typeSessionFactory) {
		super(typeSessionFactory);
		logger.info( FabricaMensagensLog.getMensagemLogConstrutor("OnibusDAOImpl") );
	}

	public ArrayList<OnibusVO> filtrar(OnibusVO vo, boolean isDisticnt,boolean isLike) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio("OnibusDAOImpl") );
		try {
			ArrayList< OnibusVO > lista = filter( vo, isDisticnt, isLike );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "OnibusDAOImpl" ) );
			return lista;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("OnibusDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( IllegalAccessException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( InvocationTargetException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}
	}
	
	@SuppressWarnings( "unchecked" )
    public ArrayList<OnibusVO> listarOnibusComLinha(LinhaVO vo) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio("OnibusDAOImpl") );
		try {
			
			Session session = getSessaoAberta();
			Query query = session.createQuery("SELECT p FROM OnibusVO p WHERE p.id IN (SELECT p.id FROM LinhaVO l INNER JOIN l.listaOnibus p WHERE l.id = :codigo)");
			query.setInteger("codigo", vo.getId());
			
			ArrayList< OnibusVO > listaOnibuss = (ArrayList< OnibusVO >) query.list();
			
			return listaOnibuss;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("OnibusDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}
	}
	
	@SuppressWarnings( "unchecked" )
    public ArrayList<OnibusVO> listarOnibusSemLinha(LinhaVO vo) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio("OnibusDAOImpl") );
		try {
			
			Session session = getSessaoAberta();
			Query query = session.createQuery("SELECT p FROM OnibusVO p WHERE p.id NOT IN (SELECT p.id FROM LinhaVO l INNER JOIN l.listaOnibus p WHERE l.id = :codigo)");
			query.setInteger("codigo", vo.getId());
			
			ArrayList< OnibusVO > listaOnibuss = (ArrayList< OnibusVO >) query.list();
			
			return listaOnibuss;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("OnibusDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}
	}

	public OnibusVO inserir(OnibusVO vo) throws InserirException {
		try {
			logger.info( FabricaMensagensLog.getMensagemLogInicio( "OnibusDAOImpl" ) );
			OnibusVO objetoPersistido = (OnibusVO) insert( vo );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "OnibusDAOImpl" ) );
			return objetoPersistido;
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", e ) );
			throw new InserirException( e.getMessage(), e );
		}
	}

	
	public void alterar(OnibusVO vo) throws AlterarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "OnibusDAOImpl" ) );
		try {
			update( vo );
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro("OnibusDAOImpl", e ) );
			throw new AlterarException( e.getMessage(), e );
		}
		logger.info( FabricaMensagensLog.getMensagemLogTermino("OnibusDAOImpl" ) );
	    
		
	}

	
	public void excluir(OnibusVO vo) throws ExcluirException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "OnibusDAOImpl" ) );
		try {
			delete( vo );
		} catch ( HibernatePersistenceException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", e ) );
			throw new ExcluirException( e.getMessage(), e );
		}
		logger.info( FabricaMensagensLog.getMensagemLogTermino( "OnibusDAOImpl" ) );
	}

	
	public ArrayList<OnibusVO> filtrarPaginacao(Paginacao<OnibusVO> pagination, OnibusVO vo, boolean isDisticnt,	boolean isLike) throws FiltrarException {
		logger.info( FabricaMensagensLog.getMensagemLogInicio( "OnibusDAOImpl" ) );
		try {
			ArrayList< OnibusVO > lista = paginacao( pagination, vo, isDisticnt, isLike );
			logger.info( FabricaMensagensLog.getMensagemLogTermino( "OnibusDAOImpl" ) );
			return lista;
		} catch ( IllegalArgumentException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( IllegalAccessException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( InvocationTargetException e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", e ) );
			throw new FiltrarException( e.getMessage(), e );
		} catch ( Exception e ) {
			logger.info( FabricaMensagensLog.getMensagemLogErro( "OnibusDAOImpl", new DesconhecidoException( e.getMessage(), e ) ) );
			throw new FiltrarException( e.getMessage(), e );
		}
		
	}
	
	@Override
    public Integer getTotalCadastrados( OnibusVO entidade, boolean isDisticnt, boolean isLike ) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		return super.getTotalCadastrados( entidade, isDisticnt, isLike );
	    
    }

}
